﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SafeScript.MetaModel
{
    public class MemberFunctionSet : INamed
    {
        public List<MemberFunction> Functions = new List<MemberFunction>();
        public string Name { get; set; }

        private FunctionSetTypeDef type;

        /// <summary>
        /// Searches for a function with the same parameters.
        /// The return type is ignored for this search.
        /// </summary>
        /// <param name="func"></param>
        /// <returns></returns>
        public MemberFunction GetEquivalentFunction(MemberFunction func)
        {
            foreach (MemberFunction f in this.Functions)
            {
                if (f.AreParametersEqualTo(func))
                    return f;
            }
            return null;
        }

        public bool Add(MemberFunction func, ErrorReport report)
        {
            // No two functions may have the same signature
            foreach (MemberFunction f in this.Functions)
            {
                if (f.AreParametersEqualTo(func))
                {
                    report.Add(new ErrorEntry(func.Node) { Type = ErrorType.DuplicateFunction, Info = this.Name });
                    return false;
                }
            }
            this.Functions.Add(func);
            return true;
        }

        public MemberFunctionSet Instantiate(Dictionary<TemplateParameterType,ITypeDef> templateArguments)
        {
            MemberFunctionSet s = new MemberFunctionSet();
            s.Name = this.Name;
            foreach( MemberFunction f in this.Functions )
                s.Functions.Add( f.Instantiate(templateArguments) as MemberFunction);
            return s;
        }

        public FunctionSetTypeDef Type
        {
            get
            {
                if (this.type != null)
                    return this.type;
                this.type = new FunctionSetTypeDef();
                foreach (MemberFunction f in this.Functions)
                    this.type.FunctionTypes.Add(f);
                return this.type;
            }
        }
    }
}
